﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Utils
{

    public struct Timestamp : IConvertible
    {
        #region 本体

        private readonly DateTime value;
        public Timestamp(DateTime date)
        {
            value = date;
        }
        public Timestamp(int timestamp)
        {
            value = ToDate(timestamp);
        }

        public Timestamp(long timestamp)
        {
            value = ToDate(timestamp);
        }
        public DateTime Value
        {
            get { return value; }
        }
        public Timestamp Add(long times)
        {
            return new Timestamp(this.value.AddSeconds(times));
        }
        public Timestamp AddYears(int times)
        {
            return new Timestamp(this.value.AddYears(times));
        }
        public Timestamp AddMonths(int times)
        {
            return new Timestamp(this.value.AddMonths(times));
        }
        public Timestamp AddDays(int times)
        {
            return new Timestamp(this.value.AddDays(times));
        }
        public Timestamp AddHours(int times)
        {
            return new Timestamp(this.value.AddHours(times));
        }

        public Timestamp AddMinutes(int times)
        {
            return new Timestamp(this.value.AddMinutes(times));
        }
        public static Timestamp Now
        {
            get { return new Timestamp(DateTime.Now); }
        }


        public static implicit operator Timestamp(long date)
        {
            return new Timestamp(ToDate(date));
        }

        public static implicit operator Timestamp(int date)
        {
            return new Timestamp(ToDate(date));
        }

        public static implicit operator Timestamp(DateTime date)
        {
            return new Timestamp(date);
        }

        public static implicit operator long(Timestamp ln)
        {
            return ln.Value.ToUnixTimestamp();
        }

        public override string ToString()
        {
            long time = this;
            return time.ToString();
        }


        private static DateTime ToDate(long timeStamp)
        {
            long lTime = long.Parse(timeStamp.ToString().PadRight(13, '0'));
            return new DateTime(1970, 1, 1).ToLocalTime().AddMilliseconds(lTime);
        }


        public TypeCode GetTypeCode()
        {
            return TypeCode.Int64;
        }


        #endregion

        public bool ToBoolean(IFormatProvider provider)
        {
            return ((IConvertible)(long)this).ToBoolean(provider);
        }

        public byte ToByte(IFormatProvider provider)
        {
            return ((IConvertible)(long)this).ToByte(provider);
        }

        public char ToChar(IFormatProvider provider)
        {
            return ((IConvertible)(long)this).ToChar(provider);
        }

        public DateTime ToDateTime(IFormatProvider provider)
        {
            return ((IConvertible)value).ToDateTime(provider);
        }

        public decimal ToDecimal(IFormatProvider provider)
        {
            return ((IConvertible)(long)this).ToDecimal(provider);
        }

        public double ToDouble(IFormatProvider provider)
        {
            return ((IConvertible)(long)this).ToDouble(provider);
        }

        public short ToInt16(IFormatProvider provider)
        {
            return (short)(long)this;
        }

        public int ToInt32(IFormatProvider provider)
        {
            return (int)(long)this;
        }

        public long ToInt64(IFormatProvider provider)
        {
            return (long)this;
        }

        public sbyte ToSByte(IFormatProvider provider)
        {
            return (sbyte)(long)this;
        }

        public float ToSingle(IFormatProvider provider)
        {
            return (float)(long)this;
        }

        public string ToString(IFormatProvider provider)
        {
            return this.ToString();
        }

        public object ToType(Type conversionType, IFormatProvider provider)
        {
            return ((IConvertible)(long)this).ToType(conversionType, provider);
        }

        public ushort ToUInt16(IFormatProvider provider)
        {
            return (ushort)(long)this;
        }

        public uint ToUInt32(IFormatProvider provider)
        {
            return (uint)(long)this;
        }

        public ulong ToUInt64(IFormatProvider provider)
        {
            return (ulong)(long)this;
        }
    }
}
